import React, { Component, cloneElement } from 'react';
import PropTypes from 'prop-types';

import styles from './style.scss';
import { noop } from '@utils';

export default class SubMenu extends Component {

    static propTypes = {
        menuKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
        parentMenu: PropTypes.object,
        rootMenu: PropTypes.object,
        activeKeys: PropTypes.array,
        expandedKeys: PropTypes.array,
        onClick: PropTypes.func,
        onSelect: PropTypes.func,
        onDeselect: PropTypes.func,
        onExpand: PropTypes.func,
        onDestory: PropTypes.func,
        isExpanded: PropTypes.bool,
        level: PropTypes.number,
        children: PropTypes.any,
        className: PropTypes.string,
        titleClassName: PropTypes.string,
        style: PropTypes.object,
    };

    static defaultProps = {
        onItemHover: noop,
        onClick: noop,
        onExpand: noop,
        isExpanded: false,
        level: 1,
        className: '',
        style: {}
    };

    static isSubMenu = true;

    onTitleClick = evt => {
        const { menuKey, onExpand } = this.props;
        let isExpanded = !this.props.isExpanded;
        this.props.onClick();
        onExpand({
            menuKey: String(menuKey),
            item: this,
            isExpanded
        });
    };
    onTitleMouseEnter = evt => {
        const { menuKey, onItemHover } = this.props;
        onItemHover({
            menuKey: String(menuKey),
            isHover: true
        });
    };
    onTitleMouseLeave = evt => {
        const { menuKey, onItemHover } = this.props;
        onItemHover({
            menuKey: String(menuKey),
            isHover: false
        });
    };
    render() {
        const props = this.props;
        const style = { ...this.props.style };
        let arrTitleCls = [styles.subMenuTitle];
        let arrCls = [styles.subMenu];
        if (props.className) {
            arrCls.push(props.className);
        }
        if (props.titleClassName) {
            arrTitleCls.push(props.titleClassName);
        }
        if (props.isActive) {
            arrTitleCls.push('active');
        }
        if (props.isExpanded) {
            arrTitleCls.push('expanded');
        }
        style.paddingLeft = props.level * 20 + 'px';
        return (
            <li className={arrCls.join(' ')}>
                <div className={arrTitleCls.join(' ')} style={style} onClick={this.onTitleClick}>
                    {this.props.title}
                    <i className={styles.subMenuArrow}></i>
                </div>
                <ul className={styles.subMenuList} style={{height: props.isExpanded ? 'auto' : 0}}>
                    {
                        this.renderChildren(props.children)
                    }
                </ul>
            </li>
        );
    }
    renderChildren(children) {
        const props = this.props;
        let childProps = {
            onClick: props.onClick,
            onSelect: props.onSelect,
            parentMenu: this,
            rootMenu: props.rootMenu,
            activeKeys: props.activeKeys,
            onDeselect: props.onDeselect,
            onDestory: props.onDestory,
            level: props.level + 1
        };
        return (
            React.Children.map(children, child => {
                const menuKey = String(child.props.menuKey);
                if (child.type.isMenuItem) {
                    return cloneElement(child, {
                        ...childProps,
                        isActive: props.activeKeys.indexOf(menuKey) !== -1,
                    });
                } else if (child.type.isSubMenu) {
                    return cloneElement(child, {
                        ...childProps,
                        isActive: props.activeKeys.indexOf(menuKey) !== -1,
                        isExpanded: props.expandedKeys.indexOf(menuKey) !== -1 ? true : false,
                        onExpand: this.onExpand,
                        expandedKeys: props.expandedKeys,
                    });
                }
                return child;
            })
        );
    }
}

